package short

import (
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/lexkong/log"
	"github.com/spf13/viper"
	. "shortURL/handler"
	"shortURL/model"
	"shortURL/pkg/errno"
	"shortURL/service"
	"shortURL/util"
	"time"
)

func Version(c *gin.Context) {
	SendResponse(c, errno.OK, map[string]string{
		"version": viper.GetString("version"),
	})
}

// 将长链转换成短链
type ShortRequest struct {
	LongUrl string `form:"long_url"`
}

func (request *ShortRequest) Valid() error {
	if request.LongUrl == "" {
		return errors.New("long_url is required")
	}

	return nil
}

func Short(c *gin.Context) {
	r := &ShortRequest{}

	if err := c.Bind(r); err != nil {
		SendResponse(c, errno.ErrBind, nil)
		return
	}

	if err := r.Valid(); err != nil {
		SendResponse(c, errno.New(errno.ErrParams, err), nil)
		return
	}

	srv := service.GetShortService()
	shortUrl, err := srv.Short(r.LongUrl)
	if err != nil {
		SendResponse(c, err, nil)
		return
	}

	SendResponse(c, errno.OK, map[string]string{
		"short_url": shortUrl,
	})
}

// 将短链转换成长链
type ExpandRequest struct {
	ShortUrl string `form:"short_url"`
}

func (request *ExpandRequest) Valid() error {
	if request.ShortUrl == "" {
		return errors.New("short_url is required")
	}

	return nil
}

func Expand(c *gin.Context) {
	r := &ExpandRequest{}

	if err := c.Bind(r); err != nil {
		SendResponse(c, errno.ErrBind, nil)
		return
	}

	if err := r.Valid(); err != nil {
		SendResponse(c, errno.New(errno.ErrParams, err), nil)
		return
	}

	srv := service.GetShortService()
	longUrl, err := srv.Expand(r.ShortUrl)
	if err != nil {
		SendResponse(c, err, nil)
		return
	}

	SendResponse(c, errno.OK, map[string]string{
		"long_url": longUrl,
	})
}

// 短链跳转
func Redirect(c *gin.Context) {
	shortededURL := c.Param("short_url")

	srv := service.GetShortService()
	longUrl, err := srv.Expand(shortededURL)
	if err != nil {
		log.Error("Redirect err", err)
		SendResponse(c, errno.InternalServerError, nil)
		return
	}

	if longUrl == "" {
		log.Infof("longurl is empty,shorturl:%s", shortededURL)
		SendResponse(c, errno.InternalServerError, nil)
		return
	}

	redirectService := &service.RedirectService{
		C: c,
		BeforeRedirect: func(c *gin.Context) {
			// 保存访问记录
			record := model.NewRecord()
			record.ShortUrl = shortededURL
			record.Ip = util.GetIP()
			record.Os = c.Request.Header.Get("User-Agent")
			record.CreateAt = time.Now()
			record.Create()
		},
	}
	redirectService.Redirect(longUrl)
}
